using RAG.Application.Dtos.User;
using RAG.Application.Services.Interfaces;
using RAG.Domain.Entities.App;
using RAG.Domain.Repositories;
using RAG.Infrastructure.Data;
using RAG.Domain.Events.User;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace RAG.Application.Services.Implementations;

public class UserService : IUserService
{
    private readonly IRepository<Users> _userRepository;
    private readonly RagAIDbContext _context;
    private readonly IMediator _mediator;

    public UserService(IRepository<Users> userRepository, RagAIDbContext context, IMediator mediator)
    {
        _userRepository = userRepository;
        _context = context;
        _mediator = mediator;
    }

    public async Task<IEnumerable<UserDto>> GetAllAsync()
    {
        try
        {
            var users = await _userRepository.GetAllAsync();
            return users.Select(user => new UserDto
            {
                Id = user.Id,
                UserName = user.UserName,
                Email = user.Email,
                PhoneNumber = user.PhoneNumber,
                AvatarUrl = user.AvatarUrl,
                Status = user.Status,
                CreatedAt = user.CreatedAt,
                UpdatedAt = user.UpdatedAt,
                Roles = user.Roles.Select(r => r.RoleName).ToList(),
                Permissions = user.Roles.SelectMany(r => r.PermissionList).Select(p => p.PermissionName).Distinct().ToList()
            });
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException($"获取用户列表失败: {ex.Message}", ex);
        }
    }

    public async Task<UserDto?> GetByUsernameAsync(string username)
    {
        try
        {
            var allUsers = await _userRepository.GetAllAsync();
            var user = allUsers.FirstOrDefault(u => u.UserName == username);
            
            if (user == null)
            {
                return null;
            }

            return new UserDto
            {
                Id = user.Id,
                UserName = user.UserName,
                Email = user.Email,
                PhoneNumber = user.PhoneNumber,
                AvatarUrl = user.AvatarUrl,
                Status = user.Status,
                CreatedAt = user.CreatedAt,
                UpdatedAt = user.UpdatedAt,
                Roles = user.Roles.Select(r => r.RoleName).ToList(),
                Permissions = user.Roles.SelectMany(r => r.PermissionList).Select(p => p.PermissionName).Distinct().ToList()
            };
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException($"获取用户 '{username}' 失败: {ex.Message}", ex);
        }
    }

    public async Task<UserDto?> GetUserByIdAsync(Guid id)
    {
        var user = await _context.Users
            .Include(u => u.Roles)
            .ThenInclude(r => r.PermissionList)
            .FirstOrDefaultAsync(u => u.Id == id);

        if (user == null)
        {
            return null;
        }

        return new UserDto
        {
            Id = user.Id,
            UserName = user.UserName,
            Email = user.Email,
            PhoneNumber = user.PhoneNumber,
            AvatarUrl = user.AvatarUrl,
            Status = user.Status,
            CreatedAt = user.CreatedAt,
            UpdatedAt = user.UpdatedAt,
            Roles = user.Roles.Select(r => r.RoleName).ToList(),
            Permissions = user.Roles.SelectMany(r => r.PermissionList).Select(p => p.PermissionName).Distinct().ToList()
        };
    }

    public async Task<UserDto> CreateUserAsync(UserDto userDto)
    {
        // 检查用户名是否已存在
        var existingUserByUsername = await _context.Users
            .FirstOrDefaultAsync(u => u.UserName == userDto.UserName);
        
        if (existingUserByUsername != null)
        {
            throw new InvalidOperationException($"用户名 '{userDto.UserName}' 已存在");
        }

        // 检查邮箱是否已存在
        var existingUserByEmail = await _context.Users
            .FirstOrDefaultAsync(u => u.Email == userDto.Email);
        
        if (existingUserByEmail != null)
        {
            throw new InvalidOperationException($"邮箱 '{userDto.Email}' 已被使用");
        }

        var user = new Users
        {
            Id = Guid.NewGuid(),
            UserName = userDto.UserName,
            Password = userDto.Password ?? "",
            Email = userDto.Email,
            PhoneNumber = userDto.PhoneNumber,
            AvatarUrl = userDto.AvatarUrl,
            Status = userDto.Status,
            CreatedAt = DateTime.UtcNow,
            UpdatedAt = DateTime.UtcNow
        };

        var createdUser = await _userRepository.CreatedAsync(user);
        
        // 发布用户创建事件
        await _mediator.Publish(new UserCreatedEvent(
            createdUser.Id, 
            createdUser.UserName, 
            createdUser.Email, 
            createdUser.CreatedAt));
        
        return new UserDto
        {
            Id = createdUser.Id,
            UserName = createdUser.UserName,
            Email = createdUser.Email,
            PhoneNumber = createdUser.PhoneNumber,
            AvatarUrl = createdUser.AvatarUrl,
            Status = createdUser.Status,
            CreatedAt = createdUser.CreatedAt,
            UpdatedAt = createdUser.UpdatedAt,
            Roles = new List<string>(),
            Permissions = new List<string>()
        };
    }

    public async Task<UserDto> UpdateUserAsync(Guid id, UserDto userDto)
    {
        var existingUser = await _context.Users
            .Include(u => u.Roles)
            .ThenInclude(r => r.PermissionList)
            .FirstOrDefaultAsync(u => u.Id == id);
            
        if (existingUser == null)
        {
            throw new InvalidOperationException($"用户ID '{id}' 不存在");
        }

        // 检查用户名是否与其他用户冲突
        var duplicateUserByUsername = await _context.Users
            .FirstOrDefaultAsync(u => u.UserName == userDto.UserName && u.Id != id);
        
        if (duplicateUserByUsername != null)
        {
            throw new InvalidOperationException($"用户名 '{userDto.UserName}' 已存在");
        }

        // 检查邮箱是否与其他用户冲突
        var duplicateUserByEmail = await _context.Users
            .FirstOrDefaultAsync(u => u.Email == userDto.Email && u.Id != id);
        
        if (duplicateUserByEmail != null)
        {
            throw new InvalidOperationException($"邮箱 '{userDto.Email}' 已被使用");
        }

        // 保存更新前的值用于事件
        var previousUserName = existingUser.UserName;
        var previousEmail = existingUser.Email;

        // 更新字段
        existingUser.UserName = userDto.UserName;
        existingUser.Email = userDto.Email;
        existingUser.PhoneNumber = userDto.PhoneNumber;
        existingUser.AvatarUrl = userDto.AvatarUrl;
        existingUser.Status = userDto.Status;
        existingUser.UpdatedAt = DateTime.UtcNow;

        var updatedUser = await _userRepository.UpdateAsync(existingUser);
        
        // 发布用户更新事件
        await _mediator.Publish(new UserUpdatedEvent(
            updatedUser.Id, 
            updatedUser.UserName, 
            updatedUser.Email, 
            updatedUser.UpdatedAt,
            previousUserName,
            previousEmail));
        
        return new UserDto
        {
            Id = updatedUser.Id,
            UserName = updatedUser.UserName,
            Email = updatedUser.Email,
            PhoneNumber = updatedUser.PhoneNumber,
            AvatarUrl = updatedUser.AvatarUrl,
            Status = updatedUser.Status,
            CreatedAt = updatedUser.CreatedAt,
            UpdatedAt = updatedUser.UpdatedAt,
            Roles = updatedUser.Roles.Select(r => r.RoleName).ToList(),
            Permissions = updatedUser.Roles.SelectMany(r => r.PermissionList).Select(p => p.PermissionName).Distinct().ToList()
        };
    }

    public async Task<bool> DeleteUserAsync(Guid id)
    {
        var user = await _context.Users.FirstOrDefaultAsync(u => u.Id == id);
        if (user == null)
        {
            return false;
        }

        // 保存用户信息用于事件
        var userId = user.Id;
        var userName = user.UserName;
        var email = user.Email;
        var deletedAt = DateTime.UtcNow;

        await _userRepository.DeleteAsync(id);
        
        // 发布用户删除事件
        await _mediator.Publish(new UserDeletedEvent(userId, userName, email, deletedAt));
        
        return true;
    }

    public async Task<IEnumerable<string>> GetUserRolesAsync(Guid userId)
    {
        var user = await _context.Users
            .Include(u => u.Roles)
            .FirstOrDefaultAsync(u => u.Id == userId);

        return user?.Roles.Select(r => r.RoleName) ?? new List<string>();
    }

    public async Task<bool> AssignRolesToUserAsync(Guid userId, IEnumerable<Guid> roleIds)
    {
        var user = await _context.Users
            .Include(u => u.Roles)
            .FirstOrDefaultAsync(u => u.Id == userId);

        if (user == null)
        {
            return false;
        }

        var roles = await _context.Roles
            .Where(r => roleIds.Contains(r.Id))
            .ToListAsync();

        // 添加新角色（避免重复）
        foreach (var role in roles)
        {
            if (!user.Roles.Any(r => r.Id == role.Id))
            {
                user.Roles.Add(role);
            }
        }

        user.UpdatedAt = DateTime.UtcNow;
        await _context.SaveChangesAsync();

        // 发布用户角色分配事件
        await _mediator.Publish(new UserRoleAssignedEvent(
            user.Id,
            user.UserName,
            roleIds,
            roles.Select(r => r.RoleName),
            DateTime.UtcNow));

        return true;
    }

    public async Task<bool> RemoveRolesFromUserAsync(Guid userId, IEnumerable<Guid> roleIds)
    {
        var user = await _context.Users
            .Include(u => u.Roles)
            .FirstOrDefaultAsync(u => u.Id == userId);

        if (user == null)
        {
            return false;
        }

        // 移除指定角色
        var rolesToRemove = user.Roles
            .Where(r => roleIds.Contains(r.Id))
            .ToList();

        foreach (var role in rolesToRemove)
        {
            user.Roles.Remove(role);
        }

        user.UpdatedAt = DateTime.UtcNow;
        await _context.SaveChangesAsync();

        return true;
    }

    public async Task<bool> UpdateUserRolesAsync(Guid userId, IEnumerable<Guid> roleIds)
    {
        var user = await _context.Users
            .Include(u => u.Roles)
            .FirstOrDefaultAsync(u => u.Id == userId);

        if (user == null)
        {
            return false;
        }

        var roles = await _context.Roles
            .Where(r => roleIds.Contains(r.Id))
            .ToListAsync();

        // 清空现有角色并添加新角色
        user.Roles.Clear();
        foreach (var role in roles)
        {
            user.Roles.Add(role);
        }

        user.UpdatedAt = DateTime.UtcNow;
        await _context.SaveChangesAsync();

        // 发布用户角色分配事件
        await _mediator.Publish(new UserRoleAssignedEvent(
            user.Id,
            user.UserName,
            roleIds,
            roles.Select(r => r.RoleName),
            DateTime.UtcNow));

        return true;
    }

    public async Task<bool> UpdateUserStatusAsync(Guid id, string newStatus)
    {
        var user = await _context.Users.FirstOrDefaultAsync(u => u.Id == id);
        if (user == null)
        {
            return false;
        }

        var oldStatus = user.Status;
        user.Status = newStatus;
        user.UpdatedAt = DateTime.UtcNow;

        await _userRepository.UpdateAsync(user);
        
        // 发布用户状态变更事件
        await _mediator.Publish(new UserStatusChangedEvent(
            user.Id,
            user.UserName,
            oldStatus,
            newStatus,
            DateTime.UtcNow));

        return true;
    }

    public async Task<bool> TestDomainEventsAsync()
    {
        try
        {
            // 测试发布各种领域事件
            await _mediator.Publish(new UserCreatedEvent(
                Guid.NewGuid(),
                "testuser",
                "test@example.com",
                DateTime.UtcNow));

            await _mediator.Publish(new UserUpdatedEvent(
                Guid.NewGuid(),
                "updateduser",
                "updated@example.com",
                DateTime.UtcNow,
                "olduser",
                "old@example.com"));

            await _mediator.Publish(new UserDeletedEvent(
                Guid.NewGuid(),
                "deleteduser",
                "deleted@example.com",
                DateTime.UtcNow));

            await _mediator.Publish(new UserRoleAssignedEvent(
                Guid.NewGuid(),
                "roleuser",
                new List<Guid> { Guid.NewGuid() },
                new List<string> { "Admin" },
                DateTime.UtcNow));

            await _mediator.Publish(new UserStatusChangedEvent(
                Guid.NewGuid(),
                "statususer",
                "active",
                "banned",
                DateTime.UtcNow));

            return true;
        }
        catch
        {
            // 记录错误但不抛出异常
            return false;
        }
    }

    public async Task<IEnumerable<string>> GetUserPermissionsAsync(Guid userId)
    {
        var user = await _context.Users
            .Include(u => u.Roles)
            .ThenInclude(r => r.PermissionList)
            .FirstOrDefaultAsync(u => u.Id == userId);

        if (user == null)
        {
            return new List<string>();
        }

        // 获取用户所有角色的权限（去重）
        var permissions = user.Roles
            .SelectMany(r => r.PermissionList)
            .Select(p => p.PermissionName)
            .Distinct()
            .ToList();

        return permissions;
    }
}